/*
 *  $Id: NumberSurface.cs 1198 2010-11-20 14:32:09Z thenn.erannor $
 *	This file is a part of Ragima CCG.
 *	(C) 2008-2010 Ragima development group.
 *
 *	Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;

using AgateLib.DisplayLib;
using AgateLib.Geometry;

namespace Ragima {
    /// <summary>
    /// Поверхность с десятью цифрами для печати чисел.
    /// </summary>
    public sealed class NumberSurface {
        private const int NumberCount = 10;

        private Surface _surface;
        private int[] _widths;
        private Rectangle[] _numbers;

        public NumberSurface(string name, int[] widths) {
            if (widths.Length != NumberCount)
                throw new ArgumentException(string.Format("Widths array must have {0} values.", NumberCount), "widths");
            _surface = new Surface(name);
            _widths = widths;
            _numbers = GetSourceRectangles();
        }

        private Rectangle[] GetSourceRectangles() {
            var rects = new Rectangle[10];
            int x = 0;
            int height = _surface.SurfaceHeight;
            for (int i = 0; i < NumberCount; i++) {
                int width = _widths[i];
                rects[i] = new Rectangle(x, 0, width, height);
                x += width;
            }
            return rects;
        }

        public Color Color {
            get { return _surface.Color; }
            set { _surface.Color = value; }
        }

        public int GetWidth(int value) {
            if (value == 0)
                return _widths[0];
            value = Math.Abs(value);
            int width = 0;
            while (value > 0) {
                width += _widths[value % 10];
                value /= 10;
            }
            return width;
        }

        private int GetWidth(int[] numbers, int start) {
            int width = 0;
            for (int i = start; i < numbers.Length; i++)
                width += _widths[numbers[i]];
            return width;
        }

        public void Draw(int x, int y, int value) {
            int start;
            var numbers = GetNumbers(value, out start);
            Draw(x, y, numbers, start);
        }

        private void Draw(int x, int y, int[] numbers, int start) {
            int len = numbers.Length - start;
            var src = new Rectangle[len];
            var dest = new Rectangle[len];
            int height = _surface.SurfaceHeight;
            for (int i = 0; i < len; i++) {
                int n = numbers[start + i];
                int width = _widths[n];
                src[i] = _numbers[n];
                dest[i] = new Rectangle(x, y, width, height);
                x += width;
            }
            _surface.DrawRects(src, dest);
        }

        public void DrawCenter(int x, int y, int value) {
            int start;
            var numbers = GetNumbers(value, out start);
            int width = GetWidth(numbers, start);
            Draw(x - width/2, y, numbers, start);
        }

        private static int[] GetNumbers(int value, out int start) {
            var numbers = new int[10];
            value = Math.Abs(value);
            if (value > 0) {
                int i = numbers.Length;
                do {
                    numbers[--i] = value % 10;
                    value /= 10;
                } while (value != 0);
                start = i;
            } else
                start = 9;
            return numbers;
        }
    }

    /// <summary>
    /// Атрибут для файла картинки с цифрами.
    /// </summary>
    public class NumberFileAttribute: DataFileAttribute {
        private int[] _widths;

        public NumberFileAttribute(string filename, int[] widths): base(filename) {
            _widths = widths;
        }

        public override object LoadData(DataFileLoader defaultLoader) {
            return new NumberSurface(FileName, _widths);
        }

    }
}
